/**
 * 
 */
package tp.pr5.instructions;

import tp.pr5.Constants;
import tp.pr5.NavigationModule;
import tp.pr5.RobotEngine;
import tp.pr5.instructions.exceptions.InstructionExecutionException;
import tp.pr5.instructions.exceptions.WrongInstructionFormatException;
import tp.pr5.items.Item;
import tp.pr5.items.ItemContainer;

/**
 * The execution of this instruction shows the information of the inventory of the robot or the complete description about the item with identifier id contained in the inventory This Instruction works if the player writes SCAN or ESCANEAR (id is not mandatory)
 *
 */
public class ScanInstruction implements Instruction {
	private ItemContainer robotContainer;
	private String id;
	
	/**
	 * It builds a default ScanInstruction
	 */
	public ScanInstruction()
	{}
	
	private ScanInstruction(String id)
	{
		this.id = id;
	}
	@Override
	/**
	 * Parses the String returning a ScanInstruction instance or throwing a WrongInstructionFormatException()
	 * @param cad - text String to parse
	 * return Instruction Reference to an instance of ScanInstruction
	 */
	public Instruction parse(String cad) throws WrongInstructionFormatException {
		String[] commands;
		commands = cad.split(" ");
		
		if (commands[0].equalsIgnoreCase("SCAN") || commands[0].equalsIgnoreCase("ESCANEAR"))
		{
			if (commands.length >= 2)
			{
				return new ScanInstruction(commands[1]);
			}
			else
			{
				return new ScanInstruction();
			}
		}
		else
			throw new WrongInstructionFormatException(cad);
	}


	@Override
    /**
     * Returns a description of the Instruction syntax. The string does not end with the line separator. It is up to the caller adding it before printing.
     * @return The Instruction's syntax.
     */
	public String getHelp() {
		return "SCAN | ESCANEAR [id]";
	}

	@Override
	/**
	 * Set the execution context. The method receives the entire engine (engine, navigation and the robot container) even though the actual implementation of execute() may not require it.
	 * @param engine - The robot engine
	 * @param navigation - The information about the game, i.e., the places, current direction and current heading to navigate
	 * @param robotContainer - The inventory of the robot
	 */
	public void configureContext(RobotEngine engine, NavigationModule navigation, ItemContainer robotContainer) {
		this.robotContainer = robotContainer;
	}

	@Override
	/**
	 * Prints the description of a concrete item or the complete inventory of the robot
	 * @throws InstructionExecutionException - When the robot does not contain the item to be scanned
	 */
	public void execute() throws InstructionExecutionException {
		
		Item item;
		item = this.robotContainer.getItem(this.id);
		if (item != null)
		{
			this.robotContainer.requestScanItem(this.id);
		}
		else if (this.id != null)
		{
			throw new InstructionExecutionException(Constants.MESSAGE_SAYS + Constants.MESSAGE_DROP_ERROR2 + this.id + Constants.LINE_SEPARATOR);
		}
		else if (this.robotContainer.numberOfItems() == 0)
		{
			throw new InstructionExecutionException(Constants.MESSAGE_SAYS + Constants.MESSAGE_EMPTY + Constants.LINE_SEPARATOR);
		}
		else
		{
			this.robotContainer.requestScanCollection();
		}
	}

}
